package evemanutool.utils.databases; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Scanner; import java.util.concurrent.ConcurrentHashMap; import au.com.bytecode.opencsv.CSVReader; import com.beimin.eveapi.account.apikeyinfo.ApiKeyInfoParser; import com.beimin.eveapi.account.apikeyinfo.ApiKeyInfoResponse; import com.beimin.eveapi.api.calllist.Call; import com.beimin.eveapi.api.calllist.CallListParser; import com.beimin.eveapi.api.calllist.CallListResponse; import com.beimin.eveapi.core.ApiAuthorization; import com.beimin.eveapi.corporation.accountbalance.AccountBalanceParser; import com.beimin.eveapi.corporation.assetlist.AssetListParser; import com.beimin.eveapi.corporation.industryjobs.IndustryJobsParser; import com.beimin.eveapi.corporation.marketorders.MarketOrdersParser; import com.beimin.eveapi.corporation.member.security.ApiSecurityMember; import com.beimin.eveapi.corporation.member.security.ApiSecurityRole; import com.beimin.eveapi.corporation.member.security.ApiSecurityTitle; import com.beimin.eveapi.corporation.member.security.MemberSecurityParser; import com.beimin.eveapi.corporation.member.security.MemberSecurityResponse; import com.beimin.eveapi.corporation.member.tracking.ApiMember; import com.beimin.eveapi.corporation.member.tracking.MemberTrackingParser; import com.beimin.eveapi.corporation.member.tracking.MemberTrackingResponse; import com.beimin.eveapi.corporation.sheet.CorpSheetParser; import com.beimin.eveapi.corporation.sheet.CorpSheetResponse; import com.beimin.eveapi.corporation.starbase.detail.StarbaseDetailParser; import com.beimin.eveapi.corporation.starbase.detail.StarbaseDetailResponse; import com.beimin.eveapi.corporation.starbase.list.ApiStarbase; import com.beimin.eveapi.corporation.starbase.list.StarbaseListParser; import com.beimin.eveapi.corporation.starbase.list.StarbaseListResponse; import com.beimin.eveapi.corporation.titles.ApiRole; import com.beimin.eveapi.corporation.titles.ApiTitle; import com.beimin.eveapi.corporation.titles.CorporationTitlesParser; import com.beimin.eveapi.corporation.titles.CorporationTitlesResponse; import com.beimin.eveapi.corporation.wallet.journal.WalletJournalParser; import com.beimin.eveapi.corporation.wallet.transactions.WalletTransactionsParser; import com.beimin.eveapi.exception.ApiException; import com.beimin.eveapi.shared.KeyType; import com.beimin.eveapi.shared.accountbalance.AccountBalanceResponse; import com.beimin.eveapi.shared.accountbalance.EveAccountBalance; import com.beimin.eveapi.shared.assetlist.AssetListResponse; import com.beimin.eveapi.shared.assetlist.EveAsset; import com.beimin.eveapi.shared.industryjobs.ApiIndustryJob; import com.beimin.eveapi.shared.industryjobs.IndustryJobsResponse; import com.beimin.eveapi.shared.locations.ApiLocation; import com.beimin.eveapi.shared.marketorders.ApiMarketOrder; import com.beimin.eveapi.shared.marketorders.MarketOrdersResponse; import com.beimin.eveapi.shared.wallet.journal.ApiJournalEntry; import com.beimin.eveapi.shared.wallet.journal.WalletJournalResponse; import com.beimin.eveapi.shared.wallet.transactions.ApiWalletTransaction; import com.beimin.eveapi.shared.wallet.transactions.WalletTransactionsResponse; import com.beimin.eveapi.utils.AccessChecker; import evemanutool.constants.DBConstants; import evemanutool.constants.ErrorConstants; import evemanutool.constants.UserPrefConstants; import evemanutool.data.cache.BlueprintAssetEntry; import evemanutool.data.cache.CorpProductionEntry; import evemanutool.data.cache.IndustryStatsEntry; import evemanutool.data.cache.WalletJournalEntry; import evemanutool.data.cache.WalletTransactionEntry; import evemanutool.data.database.AbstractLocation; import evemanutool.data.database.AbstractStation; import evemanutool.data.database.Blueprint; import evemanutool.data.database.ManuQuote; import evemanutool.data.database.Material; import evemanutool.data.database.SolarSystem; import evemanutool.data.database.Station; import evemanutool.data.display.Asset; import evemanutool.data.display.BlueprintAsset; import evemanutool.data.display.CorpMember; import evemanutool.data.display.CorpProductionQuote; import evemanutool.data.display.Fuel; import evemanutool.data.display.ManuAcquisition; import evemanutool.data.display.MarketAcquisition; import evemanutool.data.display.MarketOrder; import evemanutool.data.display.POS; import evemanutool.data.display.Supply; import evemanutool.data.general.Pair; import evemanutool.data.general.Time; import evemanutool.gui.main.EMT; import evemanutool.prefs.Preferences; import evemanutool.prefs.Preferences.API; import evemanutool.prefs.Preferences.Account; import evemanutool.utils.calc.AssetCalculator; import evemanutool.utils.calc.IndustryJobCalculator; import evemanutool.utils.calc.ProductionCalculator; import evemanutool.utils.calc.TaxCalculator; import evemanutool.utils.calc.ValueCalculator; import evemanutool.utils.datahandling.Database; import evemanutool.utils.datahandling.DatabaseHandler.Stage; import evemanutool.utils.exceptions.ApiServerException; public class CorpApiDB extends Database implements DBConstants, UserPrefConstants, ErrorConstants { //DB:s private Preferences prefs; private BlueprintDB bdb; private PriceDB pdb; private ItemDB idb; private LocationDB ldb; private TechDB tdb; private GraphicDB gdb; //Data. //API. private volatile ApiAuthorization auth; //Characters. private ConcurrentHashMap<Long, ApiMember> characterMap = new ConcurrentHashMap<>(); //CharacterId, Info. private volatile ArrayList<CorpMember> corpMembers; //Roles. private ConcurrentHashMap<Long, ApiSecurityMember> securityMap = new ConcurrentHashMap<>(); //CharcterId, SecInfo. //Info. private volatile CorpSheetResponse corpInfo; //Account balance. private ConcurrentHashMap<Integer, EveAccountBalance> accountMap = new ConcurrentHashMap<>(); //AccountKey, Balance. //Market orders. private volatile ArrayList<ApiMarketOrder> rawOrders; private volatile ArrayList<MarketOrder> sellOrders; private volatile ArrayList<MarketOrder> buyOrders; //Industry jobs. private volatile ArrayList<ApiIndustryJob> industryJobs; //Assets. private volatile ArrayList<Asset> treeAssets; private volatile ArrayList<Asset> flatAssets; private volatile ArrayList<EveAsset<EveAsset<?>>> rawAssets; //Cached values. //Blueprints. private volatile ArrayList<BlueprintAsset> bpos; private volatile ArrayList<BlueprintAssetEntry> rawBpos; private volatile ArrayList<BlueprintAssetEntry> rawOldBpos; //Wallet. private ConcurrentHashMap<Integer, ArrayList<WalletJournalEntry>> walletJournal = new ConcurrentHashMap<>(); private ConcurrentHashMap<Integer, ArrayList<WalletTransactionEntry>> walletTransactions = new ConcurrentHashMap<>(); //Statistics. private volatile ArrayList<IndustryStatsEntry> industryStats; //Production. private Collection<CorpProductionQuote> productionQuotes; //Initialized as synchronizedCollection, locks on the instance during iteration. private volatile ArrayList<CorpProductionEntry> rawProductionQuotes; private volatile ArrayList<Supply> supplies; private volatile ArrayList<MarketAcquisition> marketAcquisitions; private volatile ArrayList<ManuAcquisition> manuAcquisitions; //Starbases. private volatile ArrayList<Pair<ApiStarbase, Map<Integer, Integer>>> rawPOSList; private volatile ArrayList<POS> posList; public CorpApiDB() { super(false, true, Stage.COMPUTE, null); } public void init(Preferences prefs, BlueprintDB bdb, ItemDB idb, PriceDB pdb, LocationDB ldb, GraphicDB gdb, TechDB tdb) { this.prefs = prefs; this.bdb = bdb; this.idb = idb; this.pdb = pdb; this.ldb = ldb; this.tdb = tdb; this.gdb = gdb; } @Override public synchronized void loadRawData() throws Exception { //Read cache readFromFile(); //Create and check the API-key. try { auth = new ApiAuthorization(prefs.getAPIId(API.ID), prefs.getAPIKey(API.KEY)); //Move to prefs. } catch (Exception e) { //API access fail. throw new ApiServerException(e.getMessage()); } if (!checkAPIAuthoraization(auth)) { //Only accessMask check has failed. throw new ApiServerException(API_AUTH_ERROR_MESSAGE); } try { //Get security information. MemberSecurityParser parser = MemberSecurityParser.getInstance(); MemberSecurityResponse response = parser.getResponse(auth); for (ApiSecurityMember a : response.getMembers()) { securityMap.put(a.getCharacterID(), a); } //Get corporation members. MemberTrackingParser parser1 = MemberTrackingParser.getInstance(); MemberTrackingResponse response1 = parser1.getResponse(auth); for (ApiMember a : response1.getAll()) { characterMap.put(a.getCharacterID(), a); } //Get general corporation information CorpSheetParser parser2 = CorpSheetParser.getInstance(); corpInfo = parser2.getResponse(auth); //Get account balance. AccountBalanceParser parser3 = AccountBalanceParser.getInstance(); AccountBalanceResponse response3 = parser3.getResponse(auth); for (EveAccountBalance e : response3.getAll()) { accountMap.put(e.getAccountKey(), e); } //Get market orders. MarketOrdersParser parser4 = MarketOrdersParser.getInstance(); MarketOrdersResponse response4 = parser4.getResponse(auth); rawOrders = new ArrayList<>(response4.getAll()); //Get industry jobs. IndustryJobsParser parser5 = IndustryJobsParser.getInstance(); IndustryJobsResponse response5 = parser5.getResponse(auth); industryJobs = new ArrayList<>(response5.getAll()); //Get assets. AssetListParser parser6 = AssetListParser.getInstance(); AssetListResponse response6 = parser6.getResponse(auth); rawAssets = new ArrayList<>(response6.getAll()); //Complete Journal list. WalletJournalParser parser7 = WalletJournalParser.getInstance(); WalletJournalResponse response7; ArrayList<WalletJournalEntry> l1; WalletJournalEntry e1; for (int i = DIVISION_KEYS[0]; i < DIVISION_KEYS[DIVISION_KEYS.length - 1]; i++) { //Initiate the list. l1 = walletJournal.get(i); response7 = parser7.getResponse(auth, i); if (l1 == null) { walletJournal.put(i, new ArrayList<WalletJournalEntry>()); l1 = walletJournal.get(i); } //Add entries. for (ApiJournalEntry a : response7.getAll()) { e1 = new WalletJournalEntry(a); if (!l1.contains(e1)) { l1.add(e1); } } //Sort the list. Collections.sort(l1); } //Complete Transaction list. WalletTransactionsParser parser8 = WalletTransactionsParser.getInstance(); WalletTransactionsResponse response8; ArrayList<WalletTransactionEntry> l2; WalletTransactionEntry e2; for (int i = DIVISION_KEYS[0]; i < DIVISION_KEYS[DIVISION_KEYS.length - 1]; i++) { //Initiate the list. l2 = walletTransactions.get(i); response8 = parser8.getResponse(auth, i); if (l2 == null) { walletTransactions.put(i, new ArrayList<WalletTransactionEntry>()); l2 = walletTransactions.get(i); } //Add entries. for (ApiWalletTransaction a : response8.getAll()) { e2 = new WalletTransactionEntry(a); if (!l2.contains(e2)) { l2.add(e2); } } //Sort the list. Collections.sort(l2); } CorporationTitlesParser parser9 = CorporationTitlesParser.getInstance(); CorporationTitlesResponse response9 = parser9.getResponse(auth); for (ApiTitle a : response9.getAll()) { for (ApiSecurityMember aSM : securityMap.values()) { for (ApiSecurityTitle aST : aSM.getTitles()) { if (aST.getTitleID() == a.getTitleID()) { //Add roles. for (ApiRole aR : a.getRoles()) { addRole(aR, aSM.getRoles()); } for (ApiRole aR : a.getRolesAtBase()) { addRole(aR, aSM.getRolesAtBase()); } for (ApiRole aR : a.getRolesAtHQ()) { addRole(aR, aSM.getRolesAtHQ()); } for (ApiRole aR : a.getRolesAtOther()) { addRole(aR, aSM.getRolesAtOther()); } } } } } StarbaseListParser parser10 = StarbaseListParser.getInstance(); StarbaseListResponse response10 = parser10.getResponse(auth); ArrayList<Pair<ApiStarbase, Map<Integer, Integer>>> aL = new ArrayList<>(); for (ApiStarbase a : response10.getAll()) { StarbaseDetailParser parser11 = StarbaseDetailParser.getInstance(); StarbaseDetailResponse response11 = parser11.getResponse(auth, a.getItemID()); aL.add(new Pair<>(a, response11.getFuelMap())); } rawPOSList = aL; } catch (ApiException e) { //Convert to a ApiServerException. throw new ApiServerException(e); } //Show message. EMT.M_HANDLER.addMessage("Corp data loaded from chache and API."); } @Override public synchronized void processData() throws Exception { //Process market orders. ArrayList<MarketOrder> tmpSellOrders = new ArrayList<>(); ArrayList<MarketOrder> tmpBuyOrders = new ArrayList<>(); Station s; for (ApiMarketOrder a : rawOrders) { //Get station. s = ldb.getStationById(a.getStationID()); if ((a.getIssued().getTime() + (((long) a.getDuration()) * 24 * 3600 * 1000) - new Date().getTime()) > 0) { if (a.getBid() == 1) { //Buy order. //Avoid expired orders. tmpBuyOrders.add(new MarketOrder(a, getCorpMemberFromId(a.getCharID()), s, ldb.getRegionById(s.getRegionId()), idb.getItem(a.getTypeID()), corpInfo.getWalletDivisions().get(a.getAccountKey()))); }else { //Sell order. tmpSellOrders.add(new MarketOrder(a, getCorpMemberFromId(a.getCharID()), s, ldb.getRegionById(s.getRegionId()), idb.getItem(a.getTypeID()), corpInfo.getWalletDivisions().get(a.getAccountKey()))); } } } //Set new database to global reference. sellOrders = tmpSellOrders; buyOrders = tmpBuyOrders; //A Converted asset list, completed with extra item- and location data. treeAssets = AssetCalculator.convertCompleteAssets(rawAssets, ldb, idb); //A flattened asset list, all items after each other. flatAssets = AssetCalculator.getFlatAssets(treeAssets); //Assets, add player given names/locations and load icons for used items. //ItemId list for API call. ArrayList<Long> idList = new ArrayList<>(); for (Asset a : flatAssets) { //Add asset to id list. if (a.getAssets() != null && !a.getAssets().isEmpty() && a.getItem().getTypeId() != OFFICE_TYPEID) { //Add valid item id:s. idList.add(a.getItemID()); } //Load icon. if (a.getItem().getIcon() == null) { a.getItem().setIcon(gdb.get32Icon(a.getItem().getTypeId())); } //Load icon for location, (Station). if (a.getLocation() != null && a.getLocation() instanceof AbstractStation && ((AbstractStation) a.getLocation()).getItem().getIcon() == null) { ((AbstractStation) a.getLocation()).getItem().setIcon( gdb.get32Icon(((AbstractStation) a.getLocation()).getItem().getTypeId())); } } //Data map. HashMap<Long, ApiLocation> dataMap = new HashMap<>(); //Get data. for (ApiLocation aL : ldb.getContainerNames(auth, idList)) { dataMap.put(aL.getItemID(), aL); } //Set names. ApiLocation aL; for (Asset a : flatAssets) { aL = dataMap.get(a.getItemID()); if (aL != null) { a.setPlayerName(aL.getItemName()); } } //Get blueprints in assets. //Temporary variables. ArrayList<BlueprintAssetEntry> tmpRawBpos = new ArrayList<>(); Blueprint b = null; BlueprintAssetEntry bAE = null; int index = 0; for (Asset a : flatAssets) { b = bdb.getByBlueprintId(a.getItem().getTypeId()); if (b != null) { //0 => untouched BPO,-1 => BPO, -2 => BPC if (a.getRawQuantity() == -1) { //A BPO. bAE = new BlueprintAssetEntry(a.getItem().getTypeId(), a.getItemID(), true); tmpRawBpos.add(bAE); //Set ME/PE levels, if found in industry jobs or cache. index = rawOldBpos.indexOf(bAE); if (index >= 0) { bAE.setMe(rawOldBpos.get(index).getMe()); bAE.setPe(rawOldBpos.get(index).getPe()); } }else if (a.getRawQuantity() == 0) { //An unresearched BPO. for (int j = 0; j < a.getQuantity(); j++) { //Add BPO:s bAE = new BlueprintAssetEntry(a.getItem().getTypeId(), a.getItemID(), true); tmpRawBpos.add(bAE); } } } } //Get blueprints in research. //Update values from jobs (ME, PE). for (ApiIndustryJob iJ : industryJobs) { //0 => BPO, 1 => BPC. if (iJ.getInstalledItemCopy() == 0) { bAE = new BlueprintAssetEntry(iJ.getInstalledItemTypeID(), iJ.getInstalledItemID(), true); index = tmpRawBpos.indexOf(bAE); if (index < 0) { tmpRawBpos.add(bAE); IndustryJobCalculator.updateWithIndustryJob(iJ, bAE, bdb.getByBlueprintId(iJ.getInstalledItemTypeID())); }else { IndustryJobCalculator.updateWithIndustryJob(iJ, tmpRawBpos.get(index), bdb.getByBlueprintId(iJ.getInstalledItemTypeID())); } } } //Blueprint assets. //Temporary variables. ArrayList<BlueprintAsset> tmpBpos = new ArrayList<>(); IndustryActivity iA = null; BpoState bS = null; AbstractLocation blocation = null; //Convert all BlueprintAssetEntries. for (BlueprintAssetEntry bAE2 : tmpRawBpos) { //Get state from industryJobs if still active. for (ApiIndustryJob iJ : industryJobs) { if (iJ.getInstalledItemID() == bAE2.getItemId()) { if (!iJ.isCompleted()) { //Set activity, state and location. iA = IndustryActivity.getFromKey(iJ.getActivityID()); bS = BpoState.getState(iJ.getBeginProductionTime().getTime() < System.currentTimeMillis(), iJ.getEndProductionTime().getTime() < System.currentTimeMillis(), false, iJ.getCompletedStatus()); blocation = ldb.getLocationFromId(iJ.getContainerLocationID()); break; }else { //Clear any previous values. iA = null; bS = null; blocation = null; break; } } } //Set location from assets if not set. if (blocation == null) { blocation = AssetCalculator.getParentAssetLocation(treeAssets, bAE2.getItemId()); } //Add BPO. tmpBpos.add(new BlueprintAsset(idb.getItem(bAE2.getTypeId()), blocation, bAE2, iA, bS)); } //Starbases. //Temporary variables. ArrayList<POS> tmpPOSList = new ArrayList<>(); ApiStarbase a; ArrayList<Fuel> fL; ArrayList<Fuel> fRL; String[] nextLine; SolarSystem system; CSVReader csv; for (int i = 0; i < rawPOSList.size(); i++) { a = rawPOSList.get(i).getFst(); fL = new ArrayList<>(); fRL = new ArrayList<>(); //Parse fuel requirements. csv = new CSVReader(new FileReader(POS_FUEL_PATH), ';'); //Skip header. csv.readNext(); while ((nextLine = csv.readNext()) != null) { system = ldb.getSystemById((long) a.getLocationID()); //Right ControlTower, factionId and minSecLevel. if ( Integer.parseInt(nextLine[0]) == a.getTypeID() && (nextLine[5].equals("") || Long.parseLong(nextLine[5]) == ldb.getRegionById(system.getRegionId()).getFactionId()) && (nextLine[4].equals("") || Double.parseDouble(nextLine[4]) < system.getSecurity())) { //Add requirement. fRL.add(new Fuel(idb.getItem(Integer.parseInt(nextLine[1])), FuelPurpose.getFromKey(Integer.parseInt(nextLine[2])), 0, Integer.parseInt(nextLine[3]))); } } csv.close(); //Create fuelList. for (Entry<Integer, Integer> fuel : rawPOSList.get(i).getSnd().entrySet()) { for (Fuel fR : fRL) { if (fR.getItem().getTypeId() == fuel.getKey()) { fL.add(new Fuel(fR.getItem(), fR.getPurpose(), fuel.getValue(), fR.getReqAmount())); break; } } } //Calculate fuel-time left. long hours = 0; for (Fuel f : fL) { if (f.getPurpose() == FuelPurpose.Online && (hours == 0 || hours > f.getAmount() / f.getReqAmount())) { hours = f.getAmount() / f.getReqAmount(); } } //Create POS. //Make sure that ApiLocation isn't null. aL = dataMap.get(a.getItemID()); if (aL == null) { aL = new ApiLocation(); aL.setItemName("Unknown"); } tmpPOSList.add(new POS(a.getItemID(), aL ,idb.getItem(a.getTypeID()), (long) a.getMoonID(), ldb.getSystemById((long) a.getLocationID()), a.getStarbaseState(), a.getOnlineTimestamp(), a.getStateTimestamp(), new Time(hours * 3600 * 1000), fL, fRL)); } //Set new database to global reference. rawBpos = tmpRawBpos; bpos = tmpBpos; posList = tmpPOSList; //Show message. EMT.M_HANDLER.addMessage("Industry and asset data procesed."); } @Override public synchronized void computeData() throws Exception { ArrayList<CorpMember> tmpCorpMembers = new ArrayList<>(); for (ApiSecurityMember aSM : securityMap.values()) { tmpCorpMembers.add(new CorpMember( aSM.getCharacterID(), TaxCalculator.calculateTotalTax(aSM.getCharacterID(), walletJournal.get(DIVISION_KEYS[0])), TaxCalculator.calculateAverageWeekTax(aSM.getCharacterID(), walletJournal.get(DIVISION_KEYS[0])), ValueCalculator.getCorpMemberAccessValue(treeAssets, aSM, characterMap.get(aSM.getCharacterID()), corpInfo, prefs, pdb, accountMap), characterMap.get(aSM.getCharacterID()))); } //Add new industry stats. IndustryStatsEntry stats = new IndustryStatsEntry(new Date(), ValueCalculator.getBuyOrderEscrow(buyOrders), ValueCalculator.getSellOrderValue(buyOrders), accountMap.get(DIVISION_KEYS[prefs.getAccountIndex(Account.INDUSTRY_WALLET)]).getBalance(), ValueCalculator.getAssetValue(prefs, pdb, AssetCalculator.getFlatAssetsInCorpHangar(flatAssets, prefs.getAccountIndex(Account.INDUSTRY_HANGAR)))); //Sort first. ArrayList<IndustryStatsEntry> tmpIndustryStats = new ArrayList<>(industryStats); Collections.sort(tmpIndustryStats); //Make sure that unnecessary entries are removed. if (tmpIndustryStats.size() >= 2) { if (tmpIndustryStats.get(0).getDate().getTime() - tmpIndustryStats.get(1).getDate().getTime() < STATS_UPDATE_INTERVAL * 3600000) { tmpIndustryStats.remove(0); } } tmpIndustryStats.add(0, stats); industryStats = tmpIndustryStats; //Create/convert production data. CorpProductionQuote cQ; productionQuotes = Collections.synchronizedCollection(new ArrayList<CorpProductionQuote>()); for (CorpProductionEntry cMQE : rawProductionQuotes) { cQ = ProductionCalculator.calculateProductionQuoteFromRaw(cMQE, bdb, pdb, idb, tdb, this, prefs); if (!productionQuotes.contains(cQ)) { productionQuotes.add(cQ); } } //Create the supply data. updateSupplyData(); //Set new database to global reference. corpMembers = tmpCorpMembers; //Show message. EMT.M_HANDLER.addMessage("Production results computed."); //Last initiation step, set complete. super.setComplete(true); } @Override public void saveData() { PrintWriter out; try { //Journal. out = new PrintWriter(WALLET_JOURNAL_CACHE_PATH); for (int i = DIVISION_KEYS[0]; i < DIVISION_KEYS[DIVISION_KEYS.length - 1]; i++) { //Print delimiter between accounts. out.println(LEVEL1_DELIM + i); for (WalletJournalEntry p : walletJournal.get(i)) { out.println(p.toParseString()); } } out.flush(); out.close(); } catch (FileNotFoundException e1) { System.err.println("Could not save corp file cache: " + e1.getMessage()); } try { //Transactions. out = new PrintWriter(WALLET_TRANS_CACHE_PATH); for (int i = DIVISION_KEYS[0]; i < DIVISION_KEYS[DIVISION_KEYS.length - 1]; i++) { //Print delimiter between accounts. out.println(LEVEL1_DELIM + i); for (WalletTransactionEntry p : walletTransactions.get(i)) { out.println(p.toParseString()); } } out.flush(); out.close(); } catch (FileNotFoundException e1) { System.err.println("Could not save corp file cache: " + e1.getMessage()); } try { //Industry stats. out = new PrintWriter(INDUSTRY_STATS_CACHE_PATH); for (IndustryStatsEntry i : industryStats) { out.println(i.toParseString()); } out.flush(); out.close(); } catch (FileNotFoundException e1) { System.err.println("Could not save corp file cache: " + e1.getMessage()); } try { //Blueprint assets. out = new PrintWriter(BPO_ASSETS_CACHE_PATH); for (BlueprintAssetEntry b : rawBpos) { //Only write if bpo is researched. if (b.getMe() > 0 || b.getPe() > 0) { out.println(b.toParseString()); } } out.flush(); out.close(); } catch (FileNotFoundException e1) { System.err.println("Could not save corp file cache: " + e1.getMessage()); } try { //Production quotes. out = new PrintWriter(CORP_QUOTES_CACHE_PATH); synchronized (productionQuotes) { for (CorpProductionQuote cMQ : productionQuotes) { out.println(new CorpProductionEntry(cMQ).toParseString()); } } out.flush(); out.close(); } catch (FileNotFoundException e1) { System.err.println("Could not save corp file cache: " + e1.getMessage()); } System.out.println("---Finished saving corp data.---"); } private boolean checkAPIAuthoraization(ApiAuthorization auth) throws ApiException { //Get key info. ApiKeyInfoParser parser1 = ApiKeyInfoParser.getInstance(); ApiKeyInfoResponse response1 = parser1.getResponse(auth); //Get call info. CallListParser parser2 = CallListParser.getInstance(); CallListResponse response2 = parser2.getResponse(); ArrayList<Long> accessMasks = new ArrayList<>(); //Extract accessMasks. for (Call call : AccessChecker.getCalls(response1, response2.get())) { //Check corporation access. if (call.getType() == KeyType.Corporation) { accessMasks.add(call.getAccessMask()); } } for (long l : CORP_ACCESS_MASKS) { if (!accessMasks.contains(l)) { //Insufficient authorization. return false; } } //Sufficient authorization. return true; } private void readFromFile() { Scanner sc; int account = 0; String line; try { //Journal. ArrayList<WalletJournalEntry> l1 = null; int i = 0; sc = new Scanner(new File(WALLET_JOURNAL_CACHE_PATH)); while (sc.hasNextLine()) { i++; line = sc.nextLine(); //Set account number. if (line.startsWith(LEVEL1_DELIM)) { account = Integer.parseInt(line.substring(LEVEL1_DELIM.length())); //Initiate list. l1 = walletJournal.get(account); if (l1 == null) { walletJournal.put(account, new ArrayList<WalletJournalEntry>()); l1 = walletJournal.get(account); } }else if (!line.equalsIgnoreCase("")) { try { l1.add(new WalletJournalEntry().fromParseString(line)); } catch (Exception e) { System.err.println("Parse error for line nr: " + i + " ->" + line); e.printStackTrace(); } } } sc.close(); } catch (FileNotFoundException e) { System.err.println("Could not read corp wallet journal cache: " + e.getMessage()); } try { //Transactions. ArrayList<WalletTransactionEntry> l2 = null; int i = 0; sc = new Scanner(new File(WALLET_TRANS_CACHE_PATH)); while (sc.hasNextLine()) { i++; line = sc.nextLine(); //Set account number. if (line.startsWith(LEVEL1_DELIM)) { account = Integer.parseInt(line.substring(LEVEL1_DELIM.length())); //Initiate list. l2 = walletTransactions.get(account); if (l2 == null) { walletTransactions.put(account, new ArrayList<WalletTransactionEntry>()); l2 = walletTransactions.get(account); } }else if (!line.equalsIgnoreCase("")) { try { l2.add(new WalletTransactionEntry().fromParseString(line)); } catch (Exception e) { System.err.println("Parse error for line nr: " + i + " ->" + line); e.printStackTrace(); } } } sc.close(); } catch (Exception e) { System.err.println("Could not read corp wallet transaction cache: " + e.getMessage()); } try { //Industry stats. sc = new Scanner(new File(INDUSTRY_STATS_CACHE_PATH)); ArrayList<IndustryStatsEntry> tmpIndustryStats = new ArrayList<>(); while (sc.hasNextLine()) { try { tmpIndustryStats.add(new IndustryStatsEntry().fromParseString(sc.nextLine())); } catch (Exception e) { e.printStackTrace(); } } industryStats = tmpIndustryStats; sc.close(); } catch (Exception e) { industryStats = new ArrayList<>(); System.err.println("Could not read corp industry stats cache: " + e.getMessage()); } try { //Blueprint assets. sc = new Scanner(new File(BPO_ASSETS_CACHE_PATH)); ArrayList<BlueprintAssetEntry> tmpRawOldBpos = new ArrayList<>(); while (sc.hasNextLine()) { try { tmpRawOldBpos.add(new BlueprintAssetEntry().fromParseString(sc.nextLine())); } catch (Exception e) { e.printStackTrace(); } } rawOldBpos = tmpRawOldBpos; sc.close(); } catch (Exception e) { rawOldBpos = new ArrayList<>(); System.err.println("Could not read corp bpo stats cache: " + e.getMessage()); } try { //Production quotes. sc = new Scanner(new File(CORP_QUOTES_CACHE_PATH)); ArrayList<CorpProductionEntry> tmpRawProductionQuotes = new ArrayList<>(); while (sc.hasNextLine()) { try { tmpRawProductionQuotes.add(new CorpProductionEntry().fromParseString(sc.nextLine())); } catch (Exception e) { e.printStackTrace(); } } rawProductionQuotes = tmpRawProductionQuotes; sc.close(); } catch (Exception e) { rawProductionQuotes = new ArrayList<>(); System.err.println("Could not read corp production quote cache: " + e.getMessage()); } } private void addRole(ApiRole aR, Collection<ApiSecurityRole> l) { //Only add role if list doesn't already contain it. for (ApiSecurityRole itrASR : l) { if (itrASR.getRoleID() == aR.getRoleID()) { return; } } ApiSecurityRole aSR = new ApiSecurityRole(); aSR.setRoleID(aR.getRoleID()); aSR.setRoleName(aR.getRoleName()); l.add(aSR); } public ArrayList<BlueprintAsset> getBpos() { return bpos; } public ArrayList<Asset> getAssets() { return treeAssets; } public ArrayList<IndustryStatsEntry> getIndustryStats() { return industryStats; } public ApiMember getCorpMemberFromId(long charID) { return characterMap.get(charID); } public ArrayList<MarketOrder> getBuyOrders() { return buyOrders; } public ArrayList<MarketOrder> getSellOrders() { return sellOrders; } public ConcurrentHashMap<Integer, ArrayList<WalletTransactionEntry>> getWalletTransactions() { return walletTransactions; } public ConcurrentHashMap<Integer, ArrayList<WalletJournalEntry>> getWalletJournal() { return walletJournal; } public ArrayList<ApiIndustryJob> getIndustryJobs() { return industryJobs; } public ArrayList<Asset> getFlatAssets() { return flatAssets; } public Collection<CorpProductionQuote> getProductionQuotes() { return productionQuotes; } public ArrayList<Supply> getSupplies() { return supplies; } public ArrayList<MarketAcquisition> getMarketAcquisitions() { return marketAcquisitions; } public ArrayList<ManuAcquisition> getManuAcquisitions() { return manuAcquisitions; } public ArrayList<CorpMember> getCorpMembers() { return corpMembers; } public ArrayList<POS> getPosList() { return posList; } /* * Methods for managing/updating the production quotes. */ public boolean removeProductionQuote(CorpProductionQuote selectedQuote) { //Will try to remove the given quote and returns a boolean based on success. return productionQuotes.remove(selectedQuote); } public boolean addProductionQuote(ManuQuote quote) { //Will try to remove the given quote and returns a boolean based on success. CorpProductionQuote cQ = ProductionCalculator.calculateProductionQuoteFromQuote(quote, bdb, pdb, this, prefs); if (productionQuotes.contains(cQ)) { return false; } productionQuotes.add(cQ); return true; } public void updateSupplyData() { //Init main lists. ArrayList<Supply> tmpSupplies = new ArrayList<>(); ArrayList<MarketAcquisition> tmpMarketAcquisitions = new ArrayList<>(); ArrayList<ManuAcquisition> tmpManuAcquisitions = new ArrayList<>(); //Adds materials that are manufactured here with correct amounts. ArrayList<Material> manuMaterials = new ArrayList<>(); //Adds materials that are bought here with correct amounts. ArrayList<Material> marketMaterials = new ArrayList<>(); //Temporary variables. Supply s; Material m; int index; synchronized (productionQuotes) { for (CorpProductionQuote cMQ : productionQuotes) { //Only include if active. if (cMQ.isActive()) { for (Material m1 : cMQ.getQuote().getMatList()) { //Set the amount of material. m = new Material(m1.getItem(), m1.getAmount() * //Amount to produce depending on production chain. (cMQ.getSellTarget() - cMQ.getStock() - cMQ.getInProduction() - cMQ.getOnSale()), m1.isRecycled(), m1.getPrice(), m1.canBeManufactured(), m1.isProduced(), m1.getManufactureQuote()); if (m.isProduced()) { //Material is manufactured. index = manuMaterials.indexOf(m); //Add to manufactured. if (index < 0) { manuMaterials.add(m); }else { //Add to amount. manuMaterials.get(index).setAmount(manuMaterials.get(index).getAmount() + m.getAmount()); } for (Material m2 : m1.getManufactureQuote().getMatList()) { //Set the amount of material. m = new Material(m1.getItem(), m2.getAmount() * m.getAmount(), m2.isRecycled(), m2.getPrice(), m2.canBeManufactured(), m2.isProduced(), m2.getManufactureQuote()); //Sub-Material is bought. index = marketMaterials.indexOf(m); //Add to bought. if (index < 0) { marketMaterials.add(m); }else { //Add to amount. marketMaterials.get(index).setAmount(marketMaterials.get(index).getAmount() + m.getAmount()); } } }else { //Material is bought. index = marketMaterials.indexOf(m); //Add to bought. if (index < 0) { marketMaterials.add(m); }else { //Add to amount. marketMaterials.get(index).setAmount(marketMaterials.get(index).getAmount() + m.getAmount()); } } } } } } //Create the supply list. //Add from market. for (Material m1 : marketMaterials) { s = new Supply(m1.getItem(), 0, m1.getAmount(), 0, 0); index = tmpSupplies.indexOf(s); if (index < 0) { tmpSupplies.add(s); }else { tmpSupplies.get(index).setNeeded(tmpSupplies.get(index).getNeeded() + s.getNeeded()); } } //Add from manufacturing. for (Material m1 : manuMaterials) { s = new Supply(m1.getItem(), 0, m1.getAmount(), 0, 0); index = tmpSupplies.indexOf(s); if (index < 0) { tmpSupplies.add(s); }else { tmpSupplies.get(index).setNeeded(tmpSupplies.get(index).getNeeded() + s.getNeeded()); } } //Init supply values. long needed; double tmp; ArrayList<Asset> astL = AssetCalculator.getFlatAssetsInCorpHangar(flatAssets, prefs.getAccountIndex(Account.INDUSTRY_HANGAR)); for (Supply supply : tmpSupplies) { //Count stock. for (Asset a : astL) { if (supply.getItem().getTypeId() == a.getItem().getTypeId()) { supply.setStock(supply.getStock() + a.getQuantity()); } } //Set needed to the correct value depending on stock. //Round up since items will need to be acquired whole but only. tmp = supply.getNeeded() - supply.getStock(); //Only round up if number isn't whole. needed = (long) (tmp == (double) ((long) tmp) ? tmp : tmp + 1); supply.setNeeded(needed < 0 ? 0 : needed); //Count items on buy orders. for (MarketOrder mO : buyOrders) { if (supply.getItem().getTypeId() == mO.getItem().getTypeId()) { supply.setOnBuyOrder(supply.getOnBuyOrder() + mO.getMarketOrder().getVolRemaining()); } } //Count items on industry jobs. for (ApiIndustryJob iJ : industryJobs) { if (supply.getItem().getTypeId() == iJ.getOutputTypeID() && !iJ.isCompleted()) { //Only count from jobs that are not delivered yet. supply.setInProduction(supply.getInProduction() + (iJ.getRuns() * supply.getItem().getPortionSize())); } } //Create acquisition data. needed = 0; //Market acquisitions. for (Material m1 : marketMaterials) { if (supply.getItem().getTypeId() == m1.getItem().getTypeId()) { if (supply.getNeeded() > 0) { //Add market acquisition. needed = (int) (supply.getNeeded() > m1.getAmount() ? m1.getAmount() + 1 : supply.getNeeded()); tmpMarketAcquisitions.add(new MarketAcquisition( supply.getItem(), needed, m1.getPrice(), supply.getItem().getVolume() * needed, m1.getPrice() * needed)); } break; } } //Manufacturing acquisitions. for (Material m1 : manuMaterials) { if (supply.getItem().getTypeId() == m1.getItem().getTypeId()) { if (supply.getNeeded() - needed > 0) { needed = (int) (supply.getNeeded() - needed > m1.getAmount() ? m1.getAmount() + 1 : supply.getNeeded() - needed); tmpManuAcquisitions.add(new ManuAcquisition(m1.getManufactureQuote(), needed, supply.getInProduction(), ProductionCalculator.calculateMaterialCoverage(m1, needed, tmpSupplies), new Time((int) (m1.getManufactureQuote().getManuTime().toSeconds() * needed + 0.5)))); } break; } } } //Set new database to global reference. supplies = tmpSupplies; manuAcquisitions = tmpManuAcquisitions; marketAcquisitions = tmpMarketAcquisitions; } }